<?php
/**
 * @autor		: Federico Mart�n Cano <canofedericomartin@gmail.com>
 * @fecha		: 11-12-2011
 * @descripcion	: Clase principal de gesti�n de base de datos
 * @version 	: 2.0
 */
class DB {
	private $tabla = "";
	private $conexion;
	private $bd;
	private $datos = array();
	/** constructor
	 * descripcion: establece la conexi�n con la base de datos, y en caso de que reciba una tabla, la deja prefijada.
	 */
	function __construct($tabla = null) {
		$this->establecerConexion();
		if (!is_null($tabla)) { $this->tabla = $tabla; }
	}
	/** prefunci�n establecerConexion()
	 * descripcion: es una prefunci�n del constructor, establece la conexi�n depende
	 * si se trata del localhost o del servidor del cliente y selecciona la base de datos.
	 */
	private function establecerConexion() {
		$arr_localhost = array('localhost', '127.0.0.1');
		if (!in_array($_SERVER['HTTP_HOST'],$arr_localhost)) {
			$this->conectarServicio(STG_HOST,STG_USER,STG_PASSWORD);
			$this->seleccionarBD(STG_DB);
		} else {
			$this->conectarServicio(DEV_HOST,DEV_USER,DEV_PASSWORD);
			$this->seleccionarBD(DEV_DB);
		}
	}
	
	private function seleccionarBD($BD) {
		try {
			$this->bd = mysql_select_db($BD,$this->conexion);
			if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error al intentar seleccionar la base de datos(".$BD.").<br>");
		} catch (Exception $e) {
			$this->alertJs(mysql_errno(). " : " .mysql_error());
			exit();
		}
	}
	private function conectarServicio($host,$user,$pwd) {
		try {
			$this->conexion = mysql_connect($host,$user,$pwd);
			if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error al intentar conectar base de datos en el ".$_SERVER['HTTP_HOST']."<br>");
		} catch (Exception $e) {
			$this->alertJs(mysql_errno(). " : " .mysql_error());
			exit();
		}
	}
	public static function alertJs($mensaje) {
		echo '<script language="javascript"> alert("'.$mensaje.'"); </script>';
	}
	/** funci�n para establecer la tabla y obtenerla */
	public function establecerTabla($tabla) {
		$this->tabla = $tabla;
	}
	public function obtenerTabla() {
		return $this->tabla;
	}
	/** insertar
	 * inserta en $tabla los valores que vengan en el array, los campos estan definidos por los key del array de datos.
	 *
	 * @param array $arrDatos
	 * @param string $tabla
	 * @example:
	 * 			$arrDatos["nombre"] = Federico;
	 * 			$arrDatos["apellido"] = Cano;
	 * 			$arrDatos["email"] = canofedericomartin@gmail.com;
	 * 			$arrDatos["celular"] = 151192112;
	 * 			insertar($arrDatos,"usuarios");
	 */
	public function insertar($arrDatos = null,$tabla = null) {
		if (is_null($arrDatos)) $arrDatos = $this->datos;
		$arr_keys = array_keys($arrDatos);
		$values = "";
		$keys = "";
		if (is_null($tabla)) $tabla = $this->obtenerTabla();
		$query = "INSERT INTO ".$tabla;
		for ($i = 0; $i < count($arr_keys);$i++) {
			$keys .=$arr_keys[$i].",";
			if (is_string($arrDatos[$arr_keys[$i]])) {	$values .= "'".$arrDatos[$arr_keys[$i]]."',"; }
			else { $values .= $arrDatos[$arr_keys[$i]].","; }
		}
		$keys = substr($keys,0,strlen($keys)-1);
		$values = substr($values,0,strlen($values)-1);
		$query .= "(".$keys.") VALUES (".$values.");";
		try {
			mysql_query($query);
			if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error al intentar insertar datos en ".$tabla.".");
		} catch (Exception $e) {
			$this->alertJs(mysql_errno(). " : " .mysql_error());
			exit();
		}
	}
	
	/**
	 * traerTodo es un funci�n que se encarga de traerTodos los datos seg�n un criterio de una tabla,
	 * y los devuelve en un array indexado n�merico.
	 *
	 * @param string $criterio
	 * @param string $tabla
	 * @param string $columnas
	 * @example traerTodo("id_producto=1","nombre,fk_id_subcategoria","productos");
	 * @return array indexado n�merico
	 */
	public function traerTodo($criterio = null,$columnas = null,$tabla = null) {
		if (is_null($tabla)) $tabla = $this->obtenerTabla();
		$arrResult = array();
		$query = "SELECT ";
		if (is_null($columnas)) $query .=" * ";
		else $query .= " ".$columnas;
		$query .= " FROM ".$tabla;
		if (!is_null($criterio)) $query .= " WHERE ".$criterio;
		$query .= ";";
		$arrResult = $this->ejecutarSelect($query);
		return $arrResult;
	}
	/**
	 * traerDatos trae todos los de un registro y los carga en el objeto.
	 *
	 * @param integer $id
	 */
	public function traerDatos($id) {
		$tabla = $this->obtenerTabla();
		$arrResult = array();
		$query = "SELECT * FROM ".$tabla;
		$query .= " WHERE id=".$id;
		$query .= ";";
		$arrResult = $this->ejecutarSelect($query);
		$i = 0;
		foreach ($arrResult as $result) {
			$key = array_keys($result);
			for ($c=0;$c<round(count($key)/2,0);$c++) {
				$this->datos[$key[$i*2+1]] = $result[$key[$i*2+1]];
				$i++;
			}
		}
	}
	
	/**
	 * actualiza una tabla trayendo un array y un criterio.
	 * luego ver que podr�a mejorar los mensajes.
	 * @param array $arrDatos
	 * @param string $criterio
	 * @param string $tabla
	 * @example
	 * 	$arrDatos["nombre"]="Federico"; 
	 * 	$arrDatos["apellido"]="Cano";
	 * 	$arrDatos["email"]="canofedericomartin@gmail.com";
	 * 	$arrDatos["celular"]=1151192112;
	 * 	actualizar($arrDatos,"id_producto=1","productos");
	 */
	public function actualizar($arrDatos = null,$criterio = null,$tabla = null) {
		if (is_null($arrDatos)) $arrDatos = $this->datos;
		$arr_keys = array_keys($arrDatos);
		$values = "";
		if (is_null($tabla)) $tabla = $this->obtenerTabla();
		$query = "UPDATE ".$tabla. " SET ";
		for ($i = 0; $i < count($arr_keys);$i++) {
			$values .=$arr_keys[$i]."=";
			if (is_string($arrDatos[$arr_keys[$i]])) {	$values .= "'".$arrDatos[$arr_keys[$i]]."',"; }
			else { $values .= $arrDatos[$arr_keys[$i]].","; }
		}
		$values = substr($values,0,strlen($values)-1);
		$query .= $values;
		if (!is_null($criterio)) $query .= " WHERE ".$criterio;
		$query .= ";";
		try {
			mysql_query($query);
			if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error al intentar actualizar datos en ".$tabla.".");
		} catch (Exception $e) {
			$this->alertJs(mysql_errno(). " : " .mysql_error());
			exit();
		}
		return $query;
	}
	public function actualizarPorId($id,$arrDatos = null,$tabla = null) {
		return $this->actualizar($arrDatos,"id=".$id,$tabla);
	}
	public function guardar() {
		mysql_query("commit;");
	}
	public function deshacerUltimosCambios() {
		try {
			mysql_query("rollback;");
			if (mysql_errno() == 1181) throw new Exception("Error al intentar volver a la versi�n m�s proxima anterior.");
		} catch (Exception $e) {
			$this->alertJs($e->getMessage());
		}
	}
	/**
	 * Borra contenido en la tabla.
	 *
	 * @param string $criterio
	 * @param string $tabla
	 * @example borrar(id_material=2,"materiales");
	 */
	public function borrar($criterio = null,$tabla = null) {
		if (is_null($tabla)) $tabla = $this->obtenerTabla();
		$query = "DELETE FROM ".$tabla;
		if (!is_null($criterio)) $query .= " WHERE ".$criterio;
		$query .= ";";
		try {
			mysql_query($query);
			if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error al intentar borrar datos en ".$tabla.".");
		} catch (Exception $e) {
			$this->alertJs(mysql_errno(). " : " .mysql_error());
			exit();
		}
	}
	public function borrarPorId($id,$tabla = null) {
		$this->borrar("id=".$id,$tabla);
	}
	/**
	 * traerCombinado es una funci�n que permite hacer consulta realizando intersecci�n entre distintas tabla bajo criterios dados.
	 * selecciona que columnas y alias para cada una.
	 *
	 * @param array $arrCampos
	 * @param array $arrTablas
	 * @param string $criterios
	 * @return array indexado n�merico
	 * @example 
	 * 	$arrCampos["c.nombre"]="subcategoria";
	 * 	$arrCampos["p.nombre"]="producto";
	 * 	$arrTablas["categorias"]="c";
	 * 	$arrTablas["productos"]="p";
	 * 	$criterios = "p.fk_id_subcategoria = c.id_categoria and c.activado = 1";
	 * 	traerCombinado($arrCampos,$arrTablas,$criterios);
	 */
	public function traerCombinado($arrCampos,$arrTablas,$criterios = null) {
		$arrResult = array();
		$query = "SELECT ";
		$columns = "";
		$tablas = "";
		
		$arrKeys = array_keys($arrCampos);
		for ($i = 0; $i < count($arrCampos);$i++) $columns .= $arrKeys[$i] . " as '" . $arrCampos[$arrKeys[$i]] . "',";
		$columns = substr($columns,0,strlen($columns)-1);
		
		$arrTablasKeys = array_keys($arrTablas);
		for ($ii = 0; $ii < count($arrTablas);$ii++) $tablas .= $arrTablasKeys[$ii] . " " . $arrTablas[$arrTablasKeys[$ii]] .",";
		$tablas = substr($tablas,0,strlen($tablas)-1);
		
		$query .= $columns . " FROM ".$tablas;
		if (!is_null($criterios)) $query .= " WHERE ".$criterios;
		$query .= ";";
		$arrResult = $this->ejecutarSelect($query);
		return $arrResult;
	}
	/**
	 * Prefunci�n ejecutarSelect, realiza la consulta a base de datos con un query dado, hace las validaciones correspondientes.
	 *
	 * @param string $query
	 * @return array indexado
	 */
	private function ejecutarSelect($query) {
		$arrResult = array();
		try {
			$registros = mysql_query($query);
			if (mysql_errno() == 1146) throw new Exception("La tabla no existe.<br>");
			else {
				$i = 0;
				$reg = mysql_fetch_array($registros);
				do {
					if ((!$reg) && ($i == 0)) throw new Exception("La tabla esta vac�a.<br>");
					if (1000 < mysql_errno() && mysql_errno() < 2056) throw new Exception("Error en el SELECT.");
					else {
						$arr_keys = array_keys($reg);
						for ($ii = 0; $ii < count($arr_keys);$ii++) $arrResult[$i][$arr_keys[$ii]] = $reg[$arr_keys[$ii]];
						$i++;
					}
				} while ($reg = mysql_fetch_array($registros));
			}
		} catch (Exception $e) {
			/*echo $e->getMessage();
			echo $e->getTraceAsString();
			echo mysql_error();
			exit();*/
		}
		return $arrResult;
	}
	
	/**
	 * M�todo para establecer los datos a cargar en las tablas.
	 *
	 * @param string $campo
	 * @param unknown_type $dato
	 */
	public function establecer($campo,$dato) {
		$this->datos[$campo] = $dato;
	}
	
	/**
	 * M�todo para obtener los datos cargados por las tablas.
	 *
	 * @param string $campo
	 * @return unknown
	 */
	public function obtener($campo) {
		return $this->datos[$campo];
	}
}
?>